<?php
// 应用公共文件

use app\admin\model\Config as ConfigModel;
use general\Tree;
use think\facade\Config;
use think\facade\Db;
use think\facade\Lang;
use Qiniu\Auth;
use TencentCloud\Tci\V20190318\Models\StatInfo;

if (!function_exists('__')) {

    /**
     * 语言翻译
     * @param string $name 被翻译字符
     * @param array  $vars 替换字符数组
     * @param string $lang 翻译语言
     * @return mixed
     */
    function __(string $name, array $vars = [], string $lang = '')
    {
        if (is_numeric($name) || !$name) {
            return $name;
        }
        return Lang::get($name, $vars, $lang);
    }
}

//计算到期时间
if (!function_exists('expiration_time_fun')) {
    function expiration_time_fun($now, $day)
    {
        // $currentDateTime = new DateTime();  
        // halt($currentDateTime);
        // // 创建一个日期间隔对象  
        // $interval = new DateInterval("P{$day}D");  

        // // 使用 add 方法将天数增加到当前时间  
        // $currentDateTime->add($interval);  

        // // 将结果转换为指定格式的日期字符串  
        // $formattedDate = $currentDateTime->format('Y-m-d'); 

        // return $formattedDate;
        // 计算新的到期时间的时间戳（秒）  
        $newExpiryTimeStamp = $now + ($day * 24 * 60 * 60);

        // 如果你想要将新的到期时间格式化为日期字符串  
        $newExpiryDate = date('Y-m-d', $newExpiryTimeStamp);
        return $newExpiryDate;
    }
}
//是否到期
if (!function_exists('isOrderExpired')) {
    function isOrderExpired($expire_at)
    {
        return time() > $expire_at;
    }
}

//计算相差天数
if (!function_exists('day_remaining_fun')) {
    function day_remaining_fun($expiryDate)
    {
        // 将到期时间转换为时间戳  
        $expiryTimeStamp = strtotime($expiryDate);

        // 获取当前时间的时间戳  
        $currentTimeStamp = time();

        // 计算时间差（秒）  
        $timeDifference = $expiryTimeStamp - $currentTimeStamp;

        // 将时间差转换为天数  
        $daysRemaining = floor($timeDifference / (24 * 60 * 60));
        return $daysRemaining;
    }
}

//计算相差天数
if (!function_exists('fileModTime')) {
    function fileModTime($expiryDate)
    {
        $fileModTime =  strtotime($expiryDate);
        // 获取当前时间的时间戳  
        $currentTime = time();
        // 计算时间差（秒）  
        $timeDiff = $currentTime - $fileModTime;

        // 将时间差转换为天数  
        $timeDiffInDays = $timeDiff / (60 * 60 * 24);
        if (intval($timeDiffInDays) >= intval(get_sys_config('download_day'))) {
            return true; //大于重新收费
        } else {
            return false;
        }
    }
}

if (!function_exists('get_area')) {

    /**
     * 获取省份地区数据 按需获取
     * @throws Throwable
     */
    function get_area(): array
    {
        $province = request()->get('province', '');
        $city     = request()->get('city', '');
        $where    = ['pid' => 1, 'level' => 1];
        if ($province !== '') {
            $where['pid']   = $province;
            $where['level'] = 2;
            if ($city !== '') {
                $where['pid']   = $city;
                $where['level'] = 3;
            }
        }
        return Db::name('area')
            ->where($where)
            ->field('id as value,name as label')
            ->select()
            ->toArray();
    }
}

if (!function_exists('get_area_all')) {
    /**
     * 获取省份地区数据所有数据
     * @throws Throwable
     */
    function get_area_all(): array
    {
        $res = Db::name('area')->where('pid', '<>', 0)
            ->select()
            ->toArray();
        $data = Tree::instance()->assembleChild($res);
        return $data;
    }
}


if (!function_exists('get_nav_parent')) {
    /**
     * 获取省份地区数据所有数据
     * @throws Throwable
     */
    function get_nav_parent($id)
    {
        $res = Db::name('navigation')->select()->toArray();
        $data = Tree::instance()->init($res);
        $ids = $data->getParentsIds($id);
        return $ids;
    }
}

//数组根据字段排序 获取数组的第一个
if (!function_exists('arr_sort_asc_reset')) {
    function arr_sort_asc_reset($arr, $field)
    {
        array_multisort(array_column($arr, $field), SORT_ASC, $arr);
        return reset($arr);
    }
}

function findDeepestChildren($nodes, &$result = [])
{
    foreach ($nodes as $node) {
        if (!empty($node['children'])) {
            // 递归调用以查找更深层的children  
            findDeepestChildren($node['children'], $result);
        } else {
            // 如果没有children，则当前节点可能是最深层的  
            $result[] = $node;
        }
    }
    return $result;
}


if (!function_exists('get_table_fields')) {
    function get_table_fields($table, $field): array
    {
        if (!$table) return [];
        // 从数据库中获取表字段信息
        $columnList        =    Db::name($table)->field($field)->select()->toArray();
        $fieldList = [];
        foreach ($columnList as $key => $item) {
            $fieldList[$key]['id'] = $item['id'];
            $fieldList[$key]['name'] = $item['name'];
        }
        return $fieldList;
    }
}

if (!function_exists('get_product_fields')) {
    function get_product_fields($table, $field): array
    {
        if (!$table) return [];
        // 从数据库中获取表字段信息
        $columnList        =    Db::name($table)->field($field)->select()->toArray();
        $fieldList = [];
        foreach ($columnList as $key => $item) {
            $fieldList[$key]['id'] = $item['id'];
            $fieldList[$key]['title'] = $item['title'];
        }
        return $fieldList;
    }
}


function get_table_list(): array
{
    $tableList = [];
    $database  = config('database.connections.mysql.database');
    $tables    = Db::query("SELECT TABLE_NAME,TABLE_COMMENT FROM information_schema.TABLES WHERE table_schema = ? ", [$database]);
    foreach ($tables as $row) {
        $tableList[$row['TABLE_NAME']] = $row['TABLE_NAME'] . ($row['TABLE_COMMENT'] ? ' - ' . $row['TABLE_COMMENT'] : '');
    }
    return $tableList;
}

if (!function_exists('str_attr_to_array')) {

    /**
     * 将字符串属性列表转为数组
     * @param string $attr 属性，一行一个，无需引号，比如：class=input-class
     * @return array
     */
    function str_attr_to_array(string $attr): array
    {
        if (!$attr) return [];
        $attr     = explode("\n", trim(str_replace("\r\n", "\n", $attr)));
        $attrTemp = [];
        foreach ($attr as $item) {
            $item = explode('=', $item);
            if (isset($item[0]) && isset($item[1])) {
                $attrVal = $item[1];
                if ($item[1] === 'false' || $item[1] === 'true') {
                    $attrVal = !($item[1] === 'false');
                } elseif (is_numeric($item[1])) {
                    $attrVal = (float) $item[1];
                }
                if (strpos($item[0], '.')) {
                    $attrKey = explode('.', $item[0]);
                    if (isset($attrKey[0]) && isset($attrKey[1])) {
                        $attrTemp[$attrKey[0]][$attrKey[1]] = $attrVal;
                        continue;
                    }
                }
                $attrTemp[$item[0]] = $attrVal;
            }
        }
        return $attrTemp;
    }
}


if (!function_exists('get_sys_config')) {

    /**
     * 获取站点的系统配置，不传递参数则获取所有配置项
     * @param string $name    变量名
     * @param string $group   变量分组，传递此参数来获取某个分组的所有配置项
     * @param bool   $concise 是否开启简洁模式，简洁模式下，获取多项配置时只返回配置的键值对
     * @return mixed
     * @throws Throwable
     */
    function get_sys_config(string $name = '', string $group = '', bool $concise = true)
    {
        if ($name) {
            // 直接使用->value('value')不能使用到模型的类型格式化
            $config = configModel::cache($name, null, configModel::$cacheTag)->where('name', $name)->find();
            if ($config) $config = $config['value'];
        } else {
            if ($group) {
                $temp = configModel::cache('group' . $group, null, configModel::$cacheTag)->where('group', $group)->select()->toArray();
            } else {
                $temp = configModel::cache('sys_config_all', null, configModel::$cacheTag)->order('weigh desc')->select()->toArray();
            }
            if ($concise) {
                $config = [];
                foreach ($temp as $item) {
                    $config[$item['name']] = $item['value'];
                }
            } else {
                $config = $temp;
            }
        }
        return $config;
    }
}

//判断该字符串是否为 Json格式
if (!function_exists('isJsonBool')) {
    //判断该字符串是否为 Json格式
    function isJsonBool($data = '', $assoc = false)
    {
        $data = json_decode($data, $assoc);

        if (($data && is_object($data)) || (is_array($data) && !empty($data))) {
            return $data;
        }
        return false;
    }
}

if (!function_exists('action_in_arr')) {

    /**
     * 检测一个方法是否在传递的数组内
     * @param array $arr
     * @return bool
     */
    function action_in_arr(array $arr = []): bool
    {
        $arr = is_array($arr) ? $arr : explode(',', $arr);
        if (!$arr) {
            return false;
        }
        $arr = array_map('strtolower', $arr);
        if (in_array(strtolower(request()->action()), $arr) || in_array('*', $arr)) {
            return true;
        }
        return false;
    }
}

if (!function_exists('encrypt_password')) {

    /**
     * 加密密码
     */
    function encrypt_password($password, $salt = '', $encrypt = 'md5')
    {
        return $encrypt($encrypt($password) . $salt);
    }
}



if (!function_exists('get_upload_config')) {
    function get_upload_config()
    {
        $uploadConfig = Config::get('upload');
        $uploadConfig['maxsize'] = file_unit_to_byte($uploadConfig['maxsize']);

        $upload = request()->upload;
        if (!$upload) {
            $uploadConfig['mode'] = 'local';
            return $uploadConfig;
        }
        unset($upload['cdn']);
        return array_merge($upload, $uploadConfig);
    }
}

if (!function_exists('grouping_array')) {
    function grouping_array($arr, $byid)
    {
        $new_group = [];
        foreach ($arr as $key => $v) {
            $new_group[$v[$byid]][] = $v;
        }
        return $new_group;
    }
}



if (!function_exists('full_url_arr')) {
    /**
     * 获取资源完整url地址
     * @param string  $relativeUrl 资源相对地址 不传入则获取域名
     * @param boolean $domain      是否携带域名 或者直接传入域名
     * @return string
     */
    function full_url_arr(string $jsonUrlArr = '', bool $domain = true, $default = '')
    {
        $cdnUrl = Config::get('general.cdn_url');

        if (!$cdnUrl) {
            $cdnUrl = request()->upload['cdn'] ?? request()->domain();
        }

        if ($domain === true) {
            $domain = $cdnUrl;
        } elseif ($domain === false) {
            $domain = '';
        }

        $relativeUrl = json_decode($jsonUrlArr, true);
        $string_arr = [];
        foreach ($relativeUrl as $key => $value) {
            if (is_array($value)) {
                if (array_key_exists('url', $value)) {
                    $string_arr[] = $domain . $value['url'];
                }
            } else {
                $string_arr[] = $domain . $value;
            }
        }
        return $string_arr;
    }
}


if (!function_exists('full_url')) {
    /**
     * 获取资源完整url地址
     * @param string  $relativeUrl 资源相对地址 不传入则获取域名
     * @param boolean $domain      是否携带域名 或者直接传入域名
     * @return string
     */
    function full_url(string $relativeUrl = '', bool $domain = true, $default = '')
    {
        $cdnUrl = Config::get('general.cdn_url');

        if (!$cdnUrl) {
            $cdnUrl = request()->upload['cdn'] ?? request()->domain();
        }

        if ($domain === true) {
            $domain = $cdnUrl;
        } elseif ($domain === false) {
            $domain = '';
        }
        $relativeUrl = $relativeUrl ?: $default;

        if (!$relativeUrl) {
            return $domain;
        }

        $regex = "/^((?:[a-z]+:)?\/\/|data:image\/)(.*)/i";
        if (preg_match('/^http(s)?:\/\//', $relativeUrl) || preg_match($regex, $relativeUrl) || $domain === false) {
            return $relativeUrl;
        }

        return $domain . $relativeUrl;
    }
}



if (!function_exists('checkQiniuImageUrlExists')) {
    function checkQiniuImageUrlExists($url)
    {
        $curl = curl_init($url);
        // 不取回数据 
        curl_setopt($curl, CURLOPT_NOBODY, true);
        // 发送请求 
        $result = curl_exec($curl);
        $found = false;
        // 如果请求没有发送失败 
        if ($result !== false) {
            // 再检查http响应码是否为200 
            $statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
            halt($statusCode);
            if ($statusCode == 200) {
                $found = true;
            }
        }
        curl_close($curl);

        return $found;
    }
}



if (!function_exists('qiniu_full_url')) {
    /**
     * 获取资源完整url地址
     * @param string  $relativeUrl 资源相对地址 不传入则获取域名
     * @param boolean $domain      是否携带域名 或者直接传入域名
     * @return string
     */
    function qiniu_full_url($relativeUrl = '')
    {
        $accessKey = Config::get('general.accessKey');
        $secretKey =  Config::get('general.secretKey');
        $auth = new Auth($accessKey, $secretKey);
        $expires = 3600;
        $url = Config::get('general.cdn_url');
        $baseUrl =  $url . $relativeUrl;
        $privateUrl = $auth->privateDownloadUrl($baseUrl, $expires);
        return $privateUrl;
    }
}


if (!function_exists('qiniu_full_url_arr')) {
    /**
     * 获取资源完整url地址
     * @param string  $relativeUrl 资源相对地址 不传入则获取域名
     * @param boolean $domain      是否携带域名 或者直接传入域名
     * @return string
     */
    function qiniu_full_url_arr(string $jsonUrlArr = '', bool $domain = true, $default = '')
    {
        $cdnUrl = Config::get('general.cdn_url');

        if (!$cdnUrl) {
            $cdnUrl = request()->upload['cdn'] ?? request()->domain();
        }

        if ($domain === true) {
            $domain = $cdnUrl;
        } elseif ($domain === false) {
            $domain = '';
        }

        $relativeUrl = json_decode($jsonUrlArr, true);
        $string_arr = [];
        foreach ($relativeUrl as $key => $value) {
            if (is_array($value)) {
                if (array_key_exists('url', $value)) {
                    $string_arr[] = qiniu_full_url($value);
                }
            } else {
                $string_arr[] = qiniu_full_url($value);
            }
        }
        return $string_arr;
    }
}

if (!function_exists('file_unit_to_byte')) {
    /**
     * 将一个文件单位转为字节
     * @param string $unit 将b、kb、m、mb、g、gb的单位转为 byte
     */
    function file_unit_to_byte(string $unit): int
    {
        preg_match('/([0-9\.]+)(\w+)/', $unit, $matches);
        if (!$matches) {
            return 0;
        }
        $typeDict = ['b' => 0, 'k' => 1, 'kb' => 1, 'm' => 2, 'mb' => 2, 'gb' => 3, 'g' => 3];
        return (int) ($matches[1] * pow(1024, $typeDict[strtolower($matches[2])] ?? 0));
    }
}

if (!function_exists('curl_get')) {
    /**
     * get curl
     */
    function curl_get($url, $headers = array())
    {
        $info = curl_init();
        curl_setopt($info, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($info, CURLOPT_HEADER, 0);
        curl_setopt($info, CURLOPT_NOBODY, 0);
        curl_setopt($info, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($info, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($info, CURLOPT_SSL_VERIFYHOST, false);
        //设置header头
        curl_setopt($info, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($info, CURLOPT_URL, $url);
        $output = curl_exec($info);
        curl_close($info);
        return $output;
    }
}

if (!function_exists('curl_post')) {
    function curl_post($url, $data, $headers = array())
    {

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        //设置header头
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        // POST数据
        curl_setopt($ch, CURLOPT_POST, 1);
        // 把post的变量加上
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
        $output = curl_exec($ch);
        curl_close($ch);
        return $output;
    }
}

//对象转数组
if (!function_exists('object_to_array')) {
    function object_to_array($obj)
    {
        $_arr = is_object($obj) ? get_object_vars($obj) : $obj;
        $arr = null;
        foreach ($_arr as $key => $val) {
            $val = (is_array($val)) || is_object($val) ? object_to_array($val) : $val;
            $arr[$key] = $val;
        }
        return $arr;
    }
}

//判断是否是json字符串
if (!function_exists('isJson')) {
    function isJson($string)
    {
        // $json = json_decode($string);
        return json_last_error() === JSON_ERROR_NONE;
    }
}


if (!function_exists('getFileInfo')) {
    function getFileInfo($fileKey)
    {
        $accessKey = Config::get('general.accessKey');
        $secretKey =  Config::get('general.secretKey');
        $bucket = Config::get('general.bucket');
        // 1. 构建 EncodedEntry
        $entry = $bucket . ':' . $fileKey;
        $encodedEntry = base64UrlSafeEncode($entry);

        // 2. 生成鉴权 Token
        $auth = new Auth($accessKey, $secretKey);
        $url = 'http://rs.qiniu.com/stat/' . $encodedEntry;
        $token = $auth->authorization($url);

        // 3. 发送 HTTP 请求
        $headers = [
            'Content-Type: application/json',
            'Authorization: ' . $token['Authorization']
        ];
        $response = httpGet($url, $headers);
        // 4. 解析结果
        if ($response['code'] == 200) {
            $data = json_decode($response['body'], true);
            $mimeType = $data['mimeType'] ?? 'unknown';
            return $mimeType;
        } else {
            return json(['code' => 1, 'msg' => '获取失败: ' . $response['body']]);
        }
    }
}


/**
 * 安全的Base64编码（替换+/为-_）
 */
function base64UrlSafeEncode($data)
{
    $find = ['+', '/'];
    $replace = ['-', '_'];
    return str_replace($find, $replace, base64_encode($data));
}
/**
 * 发送 GET 请求
 */
function httpGet($url, $headers = [])
{
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HEADER, false);
    $body = curl_exec($ch);
    $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    return ['code' => $code, 'body' => $body];
}

//截取字符串key
if (!function_exists('getMimeInfo')) {
    function getMimeInfo($str){
        $path = parse_url($str, PHP_URL_PATH);
        $parts = explode('/', $path);
        $filteredParts = array_filter($parts); // 移除空元素
        $key = reset($filteredParts);
        return $key;
    }
}
